<template>
  <div>只分析，必需从左到右按顺序传递 3 张表 {{  global.columnName.evaluate }}</div>
  <div class="app-container">
    <upload-excel-component :title="'团队实战-得分汇总表'" :on-success="teamPracticeSuccess" :before-upload="beforeUpload" />
    <upload-excel-component :title="'模拟面试-得分汇总表'" :on-success="interviewScoreSuccess" :before-upload="beforeUpload" />
    <upload-excel-component :title="'学生姓名+学号表'" :on-success="allStuSuccess" :before-upload="beforeUpload" />
    <el-button class="data-stu" type="danger" v-if="excelThreeList.length > 0 && environment === 'development'"
      @click="copyStrFn">点击复制用于学生查询雷达图用数据到data/index文件中</el-button>
    <!-- 展示读取的表格数据的 -->
    <el-tabs v-if="excelOneList.length > 0" v-model="activeName" class="demo-tabs">
      <el-tab-pane :label="`各项信息查看 ${excelOneList.length} 人`" name="first">
        <el-table :data="excelOneList" border highlight-current-row style="width: 100%; margin-top: 20px">
          <!-- 列 -->
          <el-table-column sortable v-for="item of tableHeader" :key="item" :prop="item" :label="item">
            <template #default="{ row, column }">
              <div v-if="column.property === global.columnName.evaluate">
                <el-button type="success" @click="detail(row)">面试评语</el-button>
              </div>
              <span v-else>{{ formatterFn(row, column) }}</span>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
      <el-tab-pane :label="`某项低于平均分的学生 ${filterLowList.length} 人`" name="second">
        <el-table height="650" :data="filterLowList" border highlight-current-row style="width: 100%; margin-top: 20px">
          <el-table-column sortable v-for="item of tableHeader" :key="item" :label="item" :prop="item">
            <template #default="{ row, column }">
              <div v-if="column.property === global.columnName.evaluate">
                <el-button type="success" @click="detail(row)">查看详情</el-button>
              </div>
              <span v-else-if="findAvgAttr(row, column)" style="color: red;">{{ formatterFn(row, column) }}</span>
              <span v-else>{{ formatterFn(row, column) }}</span>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
      <el-tab-pane :label="`所有项高于平均分的学生 ${filterHightList.length} 人`" name="third">
        <el-table height="650" :data="filterHightList" border highlight-current-row style="width: 100%; margin-top: 20px">
          <el-table-column sortable v-for="item of tableHeader" :key="item" :label="item" :prop="item">
            <template #default="{ row, column }">
              <div v-if="column.property === global.columnName.evaluate">
                <el-button type="success" @click="detail(row)">查看详情</el-button>
              </div>
              <span v-else-if="findAvgAttr(row, column)" style="color: red;">{{ formatterFn(row, column) }}</span>
              <span v-else>{{ formatterFn(row, column) }}</span>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
      <el-tab-pane label="查看每项平均分" name="four">
        <ul>
          <li v-for="(value, key) in stuAvgObj" :key="key">
            {{ key }} : {{ value }}
          </li>
        </ul>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import ClipboardJSfrom from 'clipboard';

import UploadExcelComponent from '@/components/uploadExcel.vue'
import * as global from '@/constant'

const tableHeader = ref([]) // 页面上要显示的表格-头部列数据
const excelOneList = ref([]) // 表1默认数据（也是将来拼接了后续表的数据展示在页面表格里用）
const excelTwoList = ref([]) // 表2默认数据
const excelThreeList = ref([]) // 表3默认数据
const filterLowList = ref([]) // 筛选以后得数据（所有项低于平均分）
const filterHightList = ref([]) // 筛选以后得到数据（所有高于平均分）
const stuAvgObj = ref({}) // 平均成绩对象
const activeName = ref('first') // 当前激活的 tab 项的名字
const environment = import.meta.env.MODE // 环境变量

// 上传表格校验
const beforeUpload = (file) => {
  const isLimitTo = file.size / 1024 / 1024 < global.isLimit
  if (isLimitTo) {
    // 通过
    return true
  } else {
    // 未通过
    ElMessage({
      message: `excel文件要小于${global.isLimit}MB`,
      type: 'warning'
    })
    return false
  }
}

// 团队实战-得分汇总表数据
const teamPracticeSuccess = (resultObj) => {
  tableHeader.value = resultObj.header

  // 某些数据需要前置数据处理
  for (let prop in global.handleExcelOneObj) {
    // 遍历所有数据，执行 constant 里定义的需要处理字段并执行对应函数处理数据再保存回去
    resultObj.results.forEach(stuObj => {
      stuObj[prop] = global.handleExcelOneObj[prop](stuObj[prop])
    })
  }
  excelOneList.value = resultObj.results
}

// 模拟面试-得分汇总表数据
const interviewScoreSuccess = (resultObj) => {
  // 合并第二个表格头部列，用于页面表格展示
  tableHeader.value = [...new Set([...tableHeader.value, ...resultObj.header])]

  // 数据前置处理（某些列的值要进行转换）
  for (let prop in global.handleExcelTwoObj) {
    // 遍历第二个表格数据做处理转换
    resultObj.results.forEach(stuObj => {
      stuObj[prop] = global.handleExcelTwoObj[prop](stuObj[prop])
    })
  }
  excelTwoList.value = resultObj.results

  // 以第一个表为基础，通过名字匹配第二个表里学生相关列的数据并合并到第一个表格里数据学生对应对象中
  excelOneList.value.forEach(stuObj => {
    // 从第二个表找到名字匹配的学生信息对象
    const findTwoExcelStudent = excelTwoList.value.find(obj => obj[global.associationKey] === stuObj[global.associationKey])
    if (!findTwoExcelStudent) {
      console.error('主表里有学生，在子表中没有数据，这个学生是', stuObj[global.associationKey])
    } else {
      // 找到了，把第二个表关键属性合并到第一个对象上来
      for (let prop in findTwoExcelStudent) {
        stuObj[prop] = findTwoExcelStudent[prop]
      }
    }
  })

  // 计算需要统计列的平均分
  for (let prop in global.avgObj) {
    let personNum = 0 // 保存某项有成绩的学生人数
    const avgNum = excelOneList.value.reduce((sum, obj) => {
      if (obj[prop] == 0) {
        // 如果是 0 ，可能没有参加，不参与平均分统计
        return sum
      } else {
        personNum++
        return sum += obj[prop] * 1 // 转数字类型
      }
    }, 0) / personNum
    stuAvgObj.value[prop] = avgNum.toFixed(2) * 1
  }

  // 筛选有某项低于平均分的学生
  excelOneList.value.filter(obj => {
    // 因为有很多项，遍历结束后知道有无
    let isHave = false
    for (let prop in stuAvgObj.value) {
      if (obj[prop] < stuAvgObj.value[prop]) isHave = true
    }
    
    if (isHave) {
      // 有某项低于平均分的学生
      filterLowList.value.push(obj)
    } else {
      // 所有项都高于平均分的学生
      filterHightList.value.push(obj)
    }
  })

}

// 学生-学号汇总表
const allStuSuccess = (resultObj) => {
  tableHeader.value = [...new Set([...tableHeader.value, ...resultObj.header])]

  excelThreeList.value = resultObj.results

  excelOneList.value.forEach(stuObj => {
    // 从第二个表找到名字匹配的学生信息对象
    const student = resultObj.results.find(obj => obj[global.associationKey] === stuObj[global.associationKey])
    if (!student) {
      console.error('主表里有学生，在子表中没有数据，这个学生是', stuObj[global.associationKey])
    } else {
      // 找到了，把第二个表关键属性合并到第一个对象上来
      for (let prop in student) {
        stuObj[prop] = student[prop]
      }
    }
  })
}

// 格式化列内容
const formatterFn = (row, column) => {
  // 用列属性字符串去全局格式化规则里找
  const formatFunction = global.formatObj[column.property]
  // 如果有规则
  if (formatFunction) {
    return formatFunction(row[column.property])
  } else {
    return row[column.property]
  }
}

// 查看面试老师的建议
const detail = (row) => {
  ElMessageBox.alert(row[global.columnName.evaluate], '建议', {
    confirmButtonText: 'OK',
  })
}

// 筛选红色标记列
const findAvgAttr = (row, column) => {
  if (stuAvgObj.value[column.property]) {
    if (row[column.property] < stuAvgObj.value[column.property]) {
      return true
    } else {
      return false
    }
  } else {
    return false
  }
}

// 生成学生查询用的数据对象
const copyStrFn = () => {
  // 主要核心还是第一个 excelOneList 变量值
  // 数据结构里有值为：项目完成度, 技术能力，团队合作意识，执行能力，状态态度，回答正确率，技术得分，表达得分
  // 融合参考为：个人技术能力，团队合作意识，态度与表达
  // 公式已在 constant 里进行了字段定义
  //  * 个人技术能力 = 项目完成度(0-100) + 技术能力(0-25) + 技术得分(0-100) / 225
  //  * 团队合作意识 = 团队合作意识(0-25) / 25
  //  * 学习态度   = 执行能力(0-25) + 状态表现(0-25) / 50
  //  * 表达能力   = 表达得分(10) / 10
  // 转换结构为
  /**
   * {
   *  列描述: ['个人技术能力', '团队合作意识', '个人态度', '表达能力']
   *  平均分: [80, 15, 40, 7]
   *  学生成绩: {
   *    学生1名字：{
   *      list: [90, 24, 33, 5],
   *      suggest: '老师的建议'
   *    }
   *    学生2名字：{
   *      list: [90, 24, 33, 6],
   *      suggest: '老师的建议'
   *    }
   *  }
   * }
   */
  const result = {
    列描述: global.columnDesc,
    平均分: [0, 0, 0, 0],
    最大值: global.maxGrade,
    学生成绩: {}
  }
  // 计算每个人的分值
  excelOneList.value.forEach(stuObj => {
    // 先换算个人技术能力得分
    const personalGrade = global.induceObj.personal.reduce((sum, key) => {
      return sum += stuObj[key] * 1
    }, 0)
    // 某个人的团队合作分数
    const teamGrade = global.induceObj.team.reduce((sum, key) => {
      return sum += stuObj[key] * 1
    }, 0)
    // 某个人个人态度分数
    const introGrade = global.induceObj.intro.reduce((sum, key) => {
      return sum += stuObj[key] * 1
    }, 0)
    // 某个人表达数据
    const deliverGrade = global.induceObj.deliver.reduce((sum, key) => {
      return sum += stuObj[key] * 1
    }, 0)
    // key：为学生名字学号，value: 是学生的成绩
    result['学生成绩'][stuObj['姓名'] + stuObj['学号'].slice(4)] = {
      list: [personalGrade, teamGrade, introGrade, deliverGrade],
      suggest: stuObj['问答综合评价']
    }
  })
  // 求每个维度平均分- 排除 0 分同学不参与平均分统计
  const celArr = [{
    grade: 0, // 个人总分
    count: 0, // 不是 0 分的同学个数
  }, {
    grade: 0, // 团队总分
    count: 0, // 不是 0 分的同学个数
  }, {
    grade: 0, // 态度总分
    count: 0, // 不是 0 分的同学个数
  }, {
    grade: 0, // 表达总分
    count: 0, // 不是 0 分的同学个数
  }]
  // 遍历每个同学成绩
  Object.values(result['学生成绩']).forEach(obj => {
    // 遍历某个同学的每项成绩 list: [90, 24, 33, 7]
    obj.list.forEach((num, index) => {
      // 对应保存到统计用的 celArr 数组中
      if (num > 0) {
        celArr[index].grade += num
        celArr[index].count++
      }
    })
  })

  // 把总分/人数 => 赋予到 result 的平均分数组里
  celArr.forEach((obj, index) => {
    result['平均分'][index] = obj.grade / obj.count
  })
  // 复制所有学生的数据对象到剪贴板
  const clip = new ClipboardJSfrom('.data-stu', {
    text() {
      return JSON.stringify(result)
    }
  })
  clip.on('success', () => {
    ElMessage.success('已复制到剪切板上-请粘贴到文件中')
  })

}
</script>
